package com.bana.sys.service;

import com.bana.sys.dao.FileDAO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ResourceUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
public class FileService {

    @Resource
    private FileDAO fileDAO;

    private String getFilePath()
    {
        try {
            File path  = new File(ResourceUtils.getURL("classpath:").getPath());
            if(!path.exists()) path = new File("");
            return String.format("%s/../../../files/",path.getAbsolutePath());
        } catch (FileNotFoundException e) {
           return null;
        }
    }

    private String getTempPath()
    {
        try {
            File path  = new File(ResourceUtils.getURL("classpath:").getPath());
            if(!path.exists()) path = new File("");
            return String.format("%s/../../../temp/",path.getAbsolutePath());
        } catch (FileNotFoundException e) {
            return null;
        }
    }

    @Transactional
    public void insertFiles(String id,List<com.bana.sys.model.File> files)
    {
        if(files!=null)
        {
            for(com.bana.sys.model.File file:files)
            {
                file.setId(id);
                insertFile(file);
            }
        }
    }

    @Transactional
    public void updateFiles(String id,List<com.bana.sys.model.File> files)
    {
        if(files==null)
        {
            files=new ArrayList<>();
        }
        List<com.bana.sys.model.File> newFiles=new ArrayList<>(files);
        List<com.bana.sys.model.File> oldFiles= fileDAO.getFiles(id);

        for(com.bana.sys.model.File newFile:newFiles)
        {
            boolean needInsert=true;
            for(com.bana.sys.model.File oldFile:oldFiles)
            {
                if(newFile.getFileName().equals(oldFile.getFileName()))
                {
                    needInsert=false;
                    break;
                }
            }
            if(needInsert)
            {
                newFile.setId(id);
                insertFile(newFile);
            }
        }

        for(com.bana.sys.model.File oldFile:oldFiles)
        {
            boolean needDelete=true;
            for(com.bana.sys.model.File newFile:newFiles)
            {
                if(oldFile.getFileName().equals(newFile.getFileName()))
                {
                    needDelete=false;
                    break;
                }
            }
            if(needDelete)
            {
                deleteFile(oldFile);
            }
        }

    }

    @Transactional
    public void deleteFiles(String id)
    {
        List<com.bana.sys.model.File> files=fileDAO.getFiles(id);
        for(com.bana.sys.model.File file:files)
        {
            deleteFile(file);
        }
    }

    private void insertFile(com.bana.sys.model.File file)
    {
        fileDAO.insertFile(file);
        File oldFile=new File(getTempPath()+file.getFileName());
        File newFile=new File(getFilePath()+file.getFileName());
        oldFile.renameTo(newFile);
    }

    private void deleteFile(com.bana.sys.model.File file)
    {
        fileDAO.deleteFile(file.getId(),file.getFileName());
        new File(getFilePath()+file.getFileName()).delete();
    }

    public String saveFile(MultipartFile multipartFile) throws IOException {

        String newFileName=new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date())+
                multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf("."));
        File newFile=new File(getTempPath()+newFileName);
        File tempDirectory=new File(getTempPath());
        tempDirectory.mkdir();
        File fileDirectory=new File(getFilePath());
        fileDirectory.mkdir();
        FileOutputStream outputStream  = new FileOutputStream(newFile);
        outputStream.write(multipartFile.getBytes());
        outputStream.close();
        return newFileName;

    }

    public void deleteTempFiles()
    {
        Calendar calendar=Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY,0);
        calendar.set(Calendar.MINUTE,0);
        calendar.set(Calendar.SECOND,0);
        calendar.set(Calendar.MILLISECOND,0);

        File directory=new File(getTempPath());
        for(File file:directory.listFiles())
        {
            if(new Date(file.lastModified()).before(calendar.getTime()))
            {
                file.delete();
            }
        }
    }

}
